package mc0101.mccache.scheduler;

import mc0101.mccache.thread.LocalAndRemoteRefreshThread;
import mc0101.mccache.thread.ZcThreadPoolTaskExecutor;
import mc0101.mccache.util.CacheInvalidJudgeUtils;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.Date;

@Slf4j
@EnableScheduling
@Component
@RefreshScope
public class ZcCacheRefreshScheduler implements SchedulingConfigurer {

    @Autowired
    @Qualifier("ZcCacheThreadPoolTaskExecutorProxy")
    private ZcThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private CacheInvalidJudgeUtils cacheInvalidJudgeUtils;

    @Autowired
    private LocalAndRemoteRefreshThread localAndRemoteRefreshThread;

    @Value("${cache.refresh.job.schedule}")
    private String cron;

    /**
     * 定时执行 默认5分钟
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                // 缓存任务
                processCheckLocalCacheInValidAndRefreshSchedule();
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 任务触发，可修改任务的执行周期
                return new CronTrigger(cron).nextExecutionTime(triggerContext);
            }
        });
    }


    /**
     * 检查并刷新缓存
     */
//    @Scheduled(cron="${cache.refresh.job.schedule}")
    public void processCheckLocalCacheInValidAndRefreshSchedule() {
        log.info("*********定时任务：主动缓存刷新开始");

        long begin = System.currentTimeMillis();

        try {
            // 判定当前是否超时或者失效了，如果超时或者失效了，内部会刷新缓存的
            if (cacheInvalidJudgeUtils.isTimeOutAndInvalid()){
                log.info("缓存已超时或者失效，开始更新！");
                threadPoolTaskExecutor.execute(localAndRemoteRefreshThread);
            }else {
                log.info("缓存不需要更新！");
            }
        } catch (Exception ex){
            log.error("一级缓存获取参数时异常，可能判定版本时调用redis出现异常，降级为本地定时刷新缓存", ex);
            if(cacheInvalidJudgeUtils.isErrorTimeOut()){
                log.info("缓存更新异常！降级刷新缓存开始");
                threadPoolTaskExecutor.execute(localAndRemoteRefreshThread);
            }else{
                log.info("缓存远程版本时间未超时，不需要更新！");
            }

        } finally {
            log.info("*********定时任务：主动缓存刷新结束，消时：" + (System.currentTimeMillis() - begin) + " ms");
        }

    }

}